namespace SimpleServiceBus.EndpointMonitor.Web.Helpers.Flot.FlotOptions
{
    public class FlotAxisOptions
    {
        /// <summary>
        /// The "mode" option
        ///determines how the data is interpreted, the default of null means as
        ///decimal numbers. Use "time" for time series data.
        /// </summary>
        public FlotAxisMode? Mode { get; set; }

        /// <summary>
        /// The options "min"/"max" are the precise minimum/maximum value on the
        ///scale. If you don't specify either of them, a value will automatically
        ///be chosen based on the minimum/maximum data values.
        /// </summary>
        public double? Min { get; set; }

        /// <summary>
        /// The options "min"/"max" are the precise minimum/maximum value on the
        ///scale. If you don't specify either of them, a value will automatically
        ///be chosen based on the minimum/maximum data values.
        /// </summary>
        public double? Max { get; set; }

        /// <summary>
        /// The "autoscaleMargin" is a bit esoteric: it's the fraction of margin
        ///that the scaling algorithm will add to avoid that the outermost points
        ///ends up on the grid border. Note that this margin is only applied
        ///when a min or max value is not explicitly set. If a margin is
        ///specified, the plot will furthermore extend the axis end-point to the
        ///nearest whole tick. The default value is "null" for the x axis and
        ///0.02 for the y axis which seems appropriate for most cases.
        /// </summary>
        public double? AutoScaleMargin
        {
            get; set;
        }

        /// <summary>
        /// "labelWidth" and "labelHeight" specifies the maximum size of the tick
        /// labels in pixels. They're useful in case you need to align several
        /// plots.
        /// </summary>
        public double? LabelWidth { get; set; }

        /// <summary>
        /// "labelWidth" and "labelHeight" specifies the maximum size of the tick
        /// labels in pixels. They're useful in case you need to align several
        /// plots.
        /// </summary>
        public double? LabelHeight { get; set; }

        /// <summary>
        ///Number or ticks array or (fn: range -> ticks array)
        /// 
        ///If you don't specify any ticks, a tick generator algorithm will make
        ///some for you. The algorithm has two passes. It first estimates how
        ///many ticks would be reasonable and uses this number to compute a nice
        ///round tick interval size. Then it generates the ticks.

        ///You can specify how many ticks the algorithm aims for by setting
        ///"ticks" to a number. The algorithm always tries to generate reasonably
        ///round tick values so even if you ask for three ticks, you might get
        ///five if that fits better with the rounding. If you don't want any
        ///ticks at all, set "ticks" to 0 or an empty array.
        /// 
        /// If you want to completely override the tick algorithm, you can specify
        ///an array for "ticks", either like this:
        ///
        ///  ticks: [0, 1.2, 2.4]
        ///
        ///Or like this (you can mix the two if you like):
        ///
        ///  ticks: [[0, "zero"], [1.2, "one mark"], [2.4, "two marks"]]
        /// 
        ///For extra flexibility you can specify a function as the "ticks"
        ///parameter. The function will be called with an object with the axis
        ///min and max and should return a ticks array. Here's a simplistic tick
        ///generator that spits out intervals of pi, suitable for use on the x
        ///axis for trigonometric functions:
        ///
        ///  function piTickGenerator(axis) {
        ///    var res = [], i = Math.floor(axis.min / Math.PI);
        ///    do {
        ///      var v = i * Math.PI;
        ///      res.push([v, i + "\u03c0"]);
        ///      ++i;
        ///    } while (v < axis.max);
        ///    
        ///    return res;
        ///  }
        /// </summary>
        public object Ticks { get; set; }

        /// <summary>
        ///Directly set the tick
        ///interval size with "tickSize". If you set it to 2, you'll get ticks at
        ///2, 4, 6, etc.
        ///
        ///Note that for the time mode "tickSize" and "minTickSize" are a bit
        ///special in that they are arrays on the form "[value, unit]" where unit
        ///is one of "second", "minute", "hour", "day", "month" and "year". So
        ///you can specify
        ///
        ///  minTickSize: [1, "month"]
        ///
        ///to get a tick interval size of at least 1 month and correspondingly,
        ///if axis.tickSize is [2, "day"] in the tick formatter, the ticks have
        ///been produced with two days in-between.
        /// </summary>
        public object TickSize { get; set; }

        /// <summary>
        /// Alternatively, you can specify that you just don't want
        ///ticks at a size less than a specific tick size with "minTickSize".
        ///Note that for time series, the format is an array like [2, "month"]
        /// </summary>
        public object MinTickSize { get; set; }

        /// <summary>
        /// You can control how the ticks look like with "tickDecimals", the
        /// number of decimals to display (default is auto-detected).
        /// </summary>
        public int? TickDecimals { get; set; }

        /// <summary>
        /// Alternatively, for ultimate control over how ticks look like you can
        ///provide a function to "tickFormatter". The function is passed two
        ///parameters, the tick value and an "axis" object with information, and
        ///should return a string. The default formatter looks like this:
        ///
        ///  function formatter(val, axis) {
        ///    return val.toFixed(axis.tickDecimals);
        ///  }
        ///
        ///The axis object has "min" and "max" with the range of the axis,
        ///"tickDecimals" with the number of decimals to round the value to and
        ///"tickSize" with the size of the interval between ticks as calculated
        ///by the automatic axis scaling algorithm (or specified by you). Here's
        ///an example of a custom formatter:
        ///
        ///  function suffixFormatter(val, axis) {
        ///    if (val > 1000000)
        ///      return (val / 1000000).toFixed(axis.tickDecimals) + " MB";
        ///    else if (val > 1000)
        ///      return (val / 1000).toFixed(axis.tickDecimals) + " kB";
        ///    else
        ///      return val.toFixed(axis.tickDecimals) + " B";
        ///  }
        /// </summary>
        public object TickFormatter { get; set; }

        //Time Series Specific Options
        /// <summary>
        /// Here "timeformat" is a format string to use. You might use it like
        ///this:
        ///
        ///  xaxis: {
        ///    mode: "time"
        ///    timeformat: "%y/%m/%d"
        ///  }
        ///  
        ///This will result in tick labels like "2000/12/24". The following
        ///specifiers are supported
        ///
        ///  %h': hours
        ///  %H': hours (left-padded with a zero)
        ///  %M': minutes (left-padded with a zero)
        ///  %S': seconds (left-padded with a zero)
        ///  %d': day of month (1-31)
        ///  %m': month (1-12)
        ///  %y': year (four digits)
        ///  %b': month name (customizable)
        /// 
        /// ** The lower case 'f' in 'Timeformat' is intentional, so that 
        /// when serialized to a flot string the field will result in
        /// timeformat, which is how it is specified in the api docs.
        /// </summary>
        public string Timeformat { get; set; }

        /// <summary>
        /// You can customize the month names with the "monthNames" option. For
        ///instance, for Danish you might specify:
        ///
        ///monthNames: ["jan", "feb", "mar", "apr", "maj", "jun", "jul", "aug", "sep", "okt", "nov", "dec"]
        /// </summary>
        public string[] MonthNames { get; set; }

    }
}